<?php

Raise::load('core.RaiseDataType');
Raise::load('core.reflection.RaiseVariable');

/**
 * RaiseColor class
 * represents a Color
 *
 * @author Sam-Mauris Yong / hellclanner at live dot com
 * @license http://www.opensource.org/licenses/bsd-license New BSD License
 * @package phpraise.core.image
 * @since 1.2
 */
class RaiseColor extends RaiseDataType {

    /**
     * Red component
     * @var integer
     */
    private $red;

    /**
     * Green component
     * @var integer
     */
    private $green;

    /**
     * Blue component
     * @var integer
     */
    private $blue;
    
    /**
     * Alpha Transparency component
     * Setting this to 255 or null means no transparency
     * @var integer
     */
    private $alpha;

    /**
     * Create a new RaiseColor object
     * @param integer $red The red value (from 0 - 255)
     * @param integer $green The green value (from 0 - 255)
     * @param integer $blue The blue value (from 0 - 255)
     * @param integer $alpha (Optional) The alpha transparency value (from 0 - 255)
     */
    public function __construct($red, $green, $blue, $alpha = null) {

        $this->red($red);
        $this->green($green);
        $this->blue($blue);
        if ($alpha === null) {
            $this->alpha(null);
        } else {
            $this->alpha($alpha);
        }
    }

    /**
     * Get or set the red component of the RaiseColor object (values valid from 0-255)
     * @param integer $r (optional) The new red value to set to
     * @return integer
     */
    public function red($r = false) {
        if ($r !== false) {
            if (!RaiseVariable::isNumeric($r)) {
                throw new RaiseInvalidArgumentException('Invalid argument $r. The red component $r must be an integer.');
            }
            $this->red = $r;
        }
        return $this->red;
    }

    /**
     * Get or set the green component of the RaiseColor object (values valid from 0-255)
     * @param integer $g (optional) The new green value to set to
     * @return integer
     */
    public function green($g = false) {
        if ($g !== false) {
            if (!RaiseVariable::isNumeric($g)) {
                throw new RaiseInvalidArgumentException('Invalid argument $g. The green component $g must be an integer.');
            }
            $this->green = $g;
        }
        return $this->green;
    }

    /**
     * Get or set the blue component of the RaiseColor object (values valid from 0-255)
     * @param integer $b (optional) The new blue value to set to
     * @return integer
     */
    public function blue($b = false) {
        if ($b !== false) {
            if (!RaiseVariable::isNumeric($b)) {
                throw new RaiseInvalidArgumentException('Invalid argument $b. The blue component $b must be an integer.');
            }
            $this->blue = $b;
        }
        return $this->blue;
    }

    /**
     * Get or set the alpha component of the RaiseColor object (values valid from 0-255)
     * @param integer $a (optional) The new alpha value to set to
     * @return integer
     */
    public function alpha($a = false) {
        if ($a !== false) {
            if (!RaiseVariable::isNumeric($a) && !is_null($a)) {
                throw new RaiseInvalidArgumentException('Invalid argument $a. The alpha component $a must be an integer or set to NULL.');
            }
            $this->alpha = $a;
        }
        return $this->alpha;
    }

    /**
     * Convert the color to a HTML hex string
     * @return string
     */
    public function toHex() {
        return dechex($this->red()) . dechex($this->green()) . dechex($this->blue());
    }

    /**
     * Convert the color to a CSS rgb() string without the alpha component
     * @return string
     */
    public function toCssRGB() {
        return 'rgb(' . $this->red() . ',' . $this->green() . ',' . $this->blue() . ')';
    }

    /**
     * Convert the color to a CSS rgba() string
     * @return string
     */
    public function toCssRGBA() {
        return 'rgba(' . $this->red() . ',' . $this->green() . ',' . $this->blue() . ',' . (($this->alpha() ? $this->alpha() : 0) / 255) . ')';
    }

    /**
     * Compare whether both RaiseColor values are equal or not
     * @param RaiseColor $c
     * @return boolean
     */
    public function equals($c) {
        return $this->red() == $c->red() && $this->green() == $c->green() && $this->blue() == $c->blue() && $this->alpha() == $c->alpha();
    }

}